---------------------------------------------------------------
-- @Description：         首位逻辑
---------------------------------------------------------------
local skynet = require "skynet"
local log = require "sky_log"
local uu = require "sky_utils"
local gg = require "game_utils"

local M = {
    local_log =true,
}

--============================= Local Function =============================--
--首位最后两张牌出牌逻辑
local function check_do_last_card(handcards, main_color, outcard_history, enemy_no_color_t, friend_no_color_t)
    if #handcards > 2 then
        uu.debug_logic(1)
        return false
    end

    local card 
    --有无主牌
    local count = gg.get_main_card_count(handcards, main_color)
    if count >= 1 then 
        card = gg.check_max_main_card(handcards, main_color, outcard_history)
        if card then
            uu.debug_logic(2)
            return true, card
        else
            card = gg.check_voice_card(handcards, main_color)
            if card then
                uu.debug_logic(3)
                return true, card
            else
                card = gg.get_handcards_min_main_card(handcards, main_color)
                if card then 
                    uu.debug_logic(4)
                    return true, card
                else
                    log.error("get_min_main_card error!")
                end
            end
        end
    else
        local has_no_main_card = gg.check_has_no_enemy_has_no_color(handcards, main_color, outcard_history, enemy_no_color_t)
        if has_no_main_card==true then 
            --card = gg.check_max_vice_card(handcards, main_color)
            local max_vice_cards_t = gg.history_check_max_vice_card_t_except_maincolor(handcards, main_color, outcard_history)
            if max_vice_cards_t and next(max_vice_cards_t) then
                table.sort(max_vice_cards_t, function (a, b)
                    return a.value > b.value
                end)
                for _, v in pairs(handcards) do
                    local value = uu.calc_card_value(v)
                    if value==max_vice_cards_t[1].value then
                        card = v
                        break
                    end
                end
                if card then
                    uu.debug_logic(5)
                    return true, card
                end
            end
        end

        if gg.check_friend_has_no_main_card(friend_no_color_t, main_color) then 
            local no_color_t = gg.check_friend_has_no_self_color(handcards, friend_no_color_t) 
            if next(no_color_t) then 
                card = gg.do_out_friend_has_color(handcards, no_color_t)
                if card then
                    uu.debug_logic(6)
                    return true, card
                else
                    log.error("do_out_friend_color error!")
                end
            end
        else
            local no_color_t = gg.check_friend_has_no_self_color(handcards, friend_no_color_t)
            if next(no_color_t) then 
                card = gg.do_out_friend_has_no_color(handcards, no_color_t)
                if card then
                    uu.debug_logic(7)
                    return true, card
                else
                    log.error("do_out_friend_color error!")
                end
            end
        end

        card = uu.history_check_less_color_or_min_card(handcards, outcard_history)
        if card then
            uu.debug_logic(8)
            return true, card
        else
            log.error("do_out_less_color_or_min_card error!")
        end
    end
end

--吊主逻辑 [中文拼音]
local function do_diao_zhu(handcards, main_color, outcard_history, enemy_no_color_t, m_seatid, outcard_history_more)
    
    local card
    if gg.check_all_main_card_except_card(handcards, main_color) then 
        card = gg.get_handcards_min_main_card(handcards, main_color)
        if not card then
            log.error("do_diao_zhu1 card==nil")
        else
            uu.debug_logic(9)
            return card
        end
    end

    local left_main_cards_count = uu.history_check_color_left_cards_count(handcards, main_color, outcard_history)
    if left_main_cards_count==2 then
        if gg.check_enemy_has_no_color(enemy_no_color_t, main_color, m_seatid, outcard_history_more, false, handcards, outcard_history) then  
            return 
        else
            card = uu.get_color_middle_card(handcards, main_color)
            if not card then 
                log.error("do_diao_zhu2 card==nil")
            else
                uu.debug_logic(10)
                return card
            end 
        end
    elseif left_main_cards_count==1 then
        local left_card = uu.history_check_color_the_last_card(handcards, main_color, outcard_history)
        local max_card_value = uu.history_check_max_card({left_card}, main_color, outcard_history) 
        if max_card_value then 
            return
        else
            if gg.check_card_in_friend_handcards(handcards, left_card, enemy_no_color_t) then 
                return 
            else
                card = uu.get_color_middle_card(handcards, main_color)
                if not card then 
                    log.error("do_diao_zhu3 card==nil")
                else
                    uu.debug_logic(11)
                    return card
                end 
            end
        end
    else
        if gg.check_enemy_has_no_color(enemy_no_color_t, main_color, m_seatid, outcard_history_more, false, handcards, outcard_history) then 
            return
        else
            card = uu.history_check_second_card(handcards, main_color, outcard_history)
            if card then
                --要出比第二大的牌小的最大牌
                card = uu.get_color_middle_card(handcards, main_color)
                uu.debug_logic(12)
                return card
            else
                return
            end
        end
    end
end

--非叫分队出最大牌逻辑
local function do_out_max_card_not_call_score_team(handcards, main_color, enemy_no_color_t, outcard_history, m_seatid, outcard_history_more)
    local max_vice_cards_t = gg.history_check_max_vice_card_t_except_maincolor(handcards, main_color, outcard_history)
    if not max_vice_cards_t
    or not next(max_vice_cards_t) then
        return
    end

    --等于0的在上面已经退出流程了
    if #max_vice_cards_t == 1 then
        local friend_seat = uu.get_friend_seatid(m_seatid)
        local next_enemy = gg.check_enemy_has_no_color(enemy_no_color_t, max_vice_cards_t[1].color, m_seatid, outcard_history_more, true, handcards, outcard_history)
        local other_enemy = gg.check_enemy_has_no_color(enemy_no_color_t, max_vice_cards_t[1].color, friend_seat, outcard_history_more, true, handcards, outcard_history)
        if next_enemy==true or other_enemy==true then
            local check_no_main_card
            if next_enemy==true then
                check_no_main_card = gg.check_enemy_has_no_color(enemy_no_color_t, main_color, m_seatid, outcard_history_more, true, handcards, outcard_history)
            else
                check_no_main_card = gg.check_enemy_has_no_color(enemy_no_color_t, main_color, friend_seat, outcard_history_more, true, handcards, outcard_history)
            end

            if not check_no_main_card then
                return
            end
        end
        
        local card = uu.get_color_max_card(handcards, max_vice_cards_t[1].color)
        if card then
            uu.debug_logic(13)
            return card
        else
            log.error("do_out_max_card_not_call_score_team error")
        end
    end

    --有多个最大副牌时
    local flag = false
    local flag_2 = false
    local _color = main_color
    local friend_seat = uu.get_friend_seatid(m_seatid)
    --是否有对手没有某个花色牌
    for _, v in pairs(max_vice_cards_t) do
        flag = gg.check_enemy_has_no_color(enemy_no_color_t, v.color, m_seatid, outcard_history_more, true, handcards, outcard_history)
        if flag==true then
            _color = v.color
            flag_2 = gg.check_enemy_has_no_color(enemy_no_color_t, main_color, m_seatid, outcard_history_more, true, handcards, outcard_history)
            break
        end

        flag = gg.check_enemy_has_no_color(enemy_no_color_t, v.color, friend_seat, outcard_history_more, true, handcards, outcard_history)
        if flag==true then
            _color = v.color
            flag_2 = gg.check_enemy_has_no_color(enemy_no_color_t, main_color, friend_seat, outcard_history_more, true, handcards, outcard_history)
            break
        end
     
        local card = uu.history_check_less_color_max_card(handcards, outcard_history)
        if card then
            uu.debug_logic(45)
            return card
        else
            log.error("history_check_less_color_max_card_1 error!")
        end
    end

    if flag_2==true then
        local card = uu.history_check_less_color_max_card(handcards, outcard_history)
        if card then
            uu.debug_logic(46)
            return card
        else
            log.error("history_check_less_color_max_card_2 error!")
        end
    end

    for i=1, 4 do
        if i~=main_color
        and (_color~=i) then 
            local value = uu.history_check_max_card(handcards, i, outcard_history)
            if value then
                local card = uu.history_check_less_color_max_card(handcards, outcard_history)
                if card then
                    uu.debug_logic(47)
                    return card
                else
                    log.error("history_check_less_color_max_card_2 error!")
                end
            end
        end
    end
end

--非叫分队出牌逻辑
local function do_card_not_call_score_team(handcards, main_color, outcard_history, enemy_no_color_t, m_seatid, outcard_history_more)
    local card
    --非叫分队检测手中是否有最大的主牌, 是，则回到外面叫分队出最大牌逻辑
    if uu.history_check_max_card(handcards, main_color, outcard_history) then
        uu.debug_logic(15)
        return true
    else
        --没有最大主牌，再检测是否有多张主牌， 是，同样回到外面叫分队出最大牌逻辑
        if gg.check_has_more_maincard(handcards, main_color)==true then 
            uu.debug_logic(16)
            return true
        else
            --没有多张主牌,则走非叫分队出最大牌逻辑
            card = do_out_max_card_not_call_score_team(handcards, main_color, enemy_no_color_t, outcard_history, m_seatid, outcard_history_more)
            if card then 
                uu.debug_logic(17)
                return false, card
            else
                --叫分队没有最大出牌，则走去公共逻辑
                uu.debug_logic(18)
                return false
            end
        end
    end
end

--叫分队出最大牌逻辑
local function do_out_max_card_call_score_team(handcards, main_color, outcard_history, enemy_no_color_t, m_seatid, outcard_history_more)
    if uu.history_check_max_card(handcards, main_color, outcard_history) then
        if gg.check_enemy_has_no_color(enemy_no_color_t, main_color, m_seatid, outcard_history_more, false, handcards, outcard_history)~=true then
            local card = gg.get_handcards_max_main_card(handcards, main_color)
            if card then 
                uu.debug_logic(19)
                return card
            else
                log.error("get_handcards_max_main_card error")
            end 
        end
    end

    --a.结合历史出牌是否有副花色中有最大的牌
    local card_t = {}
    for i=1, 4 do
        if i~=main_color then 
            local value = uu.history_check_max_card(handcards, i, outcard_history)
            if value then
                local card = uu.get_card_by_color_and_value(i, value)
                table.insert(card_t, card) 
            end
        end
    end

    --a.否
    if #card_t==0 then 
        return
    end

    --a.是-->b.结合历史出牌是否有多个副花色中有最大的牌

    --b.否
    if #card_t==1 then 
        local the_color = uu.calc_card_color(card_t[1])
        if gg.check_enemy_has_no_color_and_main_card(the_color, enemy_no_color_t, main_color) then 
            return 
        else
            local card = uu.get_color_max_card(handcards, the_color)
            if card then
                uu.debug_logic(20)
                return card
            end
        end
    end

    --b.是
    for _, v in pairs(card_t) do
        local the_color = uu.calc_card_color(v)
        if gg.check_enemy_has_no_color_and_main_card(the_color, enemy_no_color_t, main_color) then 
            local card = uu.history_check_less_color_max_card(handcards, outcard_history)
            uu.debug_logic(21)
            return card
        end
    end

    --
    local colors = {}
    for _, v in pairs(card_t) do
        local _color_ = uu.calc_card_color(v)
        colors[_color_] = true
    end
    local card = gg.get_handcards_less_color_max_card_in_colors(handcards, colors)
    if card then
        uu.debug_logic(22)
        return card
    else
        log.error("get_handcards_less_color_max_card_in_colors error")
    end
end

--叫分队出牌逻辑
local function do_card_call_score_team(handcards, main_color, outcard_history, enemy_no_color_t, m_seatid, outcard_history_more)
    local card = do_out_max_card_call_score_team(handcards, main_color, outcard_history, enemy_no_color_t, m_seatid, outcard_history_more)
    if card then 
        uu.debug_logic(23)
        return card
    end

    --叫分队出最大牌逻辑检测发现无最大可出牌时：是否有多张主牌, 否，则去外层走公共逻辑;是，则进行下一步
    if gg.check_has_more_maincard(handcards, main_color) then 
        --是否有单张副牌:否则执行 history_check_has_all_color_card, 是，则进行下一步逻辑
        local single_color_t = gg.check_has_single_vice_card(handcards, main_color)
        if next(single_color_t) then 
            --是否除了这张副牌外全是主牌：否，则出牌； 是则 也去执行 history_check_has_all_color_card
            if not gg.check_all_main_card_except_card(handcards, main_color) then
                card = gg.history_check_less_color_vice_card(handcards, outcard_history, main_color, single_color_t)
                if card then 
                    uu.debug_logic(24)
                    return card
                else
                    log.error("history_check_less_color_vice_card error!")
                end
            end
        end
            
        --结合出牌历史，判断是否主牌全在手中
        if uu.history_check_has_all_color_card(handcards, main_color, outcard_history) then
            --是，则去外层走公共逻辑
        else
            --否，则走吊主逻辑
            card = do_diao_zhu(handcards, main_color, outcard_history, enemy_no_color_t, m_seatid, outcard_history_more)
            if card then 
                --若吊主成功则返回牌，没有成功则同样去外层走公共逻辑
                uu.debug_logic(25)
                return card
            end
        end
    end 
end

--某花色第一、二轮出牌
local function do_out_color_first(handcards, main_color, the_color, outcard_history, ext_colors)
    local card = uu.history_check_second_card(handcards, the_color, outcard_history)
    --log.info("card1=", card)
    --log.info("ext_colors=", ext_colors)
    if ext_colors and 
    next(ext_colors) then
        for _, v in pairs(ext_colors) do
            card = uu.history_check_second_card(handcards, v, outcard_history)
            if card then
                the_color = uu.calc_card_color(card)
                break
            end
        end
    end
    --log.info("card2=", card)
    --log.info("the_color=", the_color)
    if card then 
        local t = uu.get_handcards_one_color(handcards, the_color)
        if #t==1 then
            uu.debug_logic(26)
            return card
        else
            card = uu.get_color_middle_card(handcards, the_color)
            if card then
                uu.debug_logic(27)
                return card
            else
                log.error("do_out_color_first_1 error")
            end
        end
    else
        local main_card_count = gg.get_main_card_count(handcards, main_color)
        --log.info("main_card_count=", main_card_count)
        local temp_t = {}
        for _, v in pairs(handcards) do
            local _color_ = uu.calc_card_color(v)
            for _, _vv in pairs(ext_colors) do
                if _color_==_vv then
                    table.insert(temp_t, v)
                end
            end
        end
     
        if main_card_count > 0 then
            --策划说要除开主牌
            card = gg.get_handcards_less_color_max_card_except_color(temp_t, main_color)
            if card then
                uu.debug_logic(28)
                return card
            else
                log.error("do_out_color_first_2 error")
            end
        else
            card = uu.get_more_color_max_card(handcards)
            if card then
                uu.debug_logic(29)
                return card
            else
                log.error("do_out_color_first_3 error")
            end
        end
    end
end

--流程图上可公用的一部分逻辑
local function do_common_logic(handcards, main_color, outcard_history, enemy_no_color_t, friend_no_color_t, outcard_history_more)
    local card

    local no_color_t = gg.check_friend_has_no_color_t(friend_no_color_t, main_color)
    --log.info("no_color_t=", no_color_t)
    --检测队友是否没有某个花色
    if gg.check_friend_has_no_color(friend_no_color_t) then
        --是：则检测队友是否没有主牌
        if not gg.check_friend_has_no_main_card(friend_no_color_t, main_color) then
            --否， 再检测我自己是否有该花色
            card = gg.check_self_has_color(handcards, no_color_t)
            --有，则出牌
            if card then 
                uu.debug_logic(30)
                return card
            end
        end
    end

    --结合出牌历史，检测对手是否没有某个花色牌且有主牌
    local the_no_color = gg.check_enemy_has_no_color_s_and_main_card(handcards, {1,2,3,4}, enemy_no_color_t, main_color) 
    --log.info("the_no_color=", the_no_color)
    if the_no_color then 
        --是否除该花色和主牌外，无其他花色牌
        if gg.check_no_card_except_color_and_main_card(handcards, the_no_color, main_color) then 
            --是否有该花色最大的牌
            if uu.history_check_max_card(handcards, the_no_color, outcard_history) then 
                --是，则出手中该花色第二大的牌
                card = uu.get_color_middle_card(handcards, the_no_color)
                if card then 
                    uu.debug_logic(31)
                    return card
                else
                    log.error("get_color_middle_card error!")
                end
            else
                --否，则出手中该花色最大的牌
                card = uu.get_color_max_card(handcards, the_no_color)
                if card then
                    uu.debug_logic(32)
                    return card
                else
                    log.error("get_color_max_card error!")
                end
            end
        end
    end

    --除对手没有的花色外，是否有某种花色是第1，2轮出牌
    local _color = gg.check_color_first_out_except_enemy(enemy_no_color_t, outcard_history_more, handcards)
    --log.info("color=", _color)
    --策划说要去主牌
    for k, v in pairs(_color) do
        if v==main_color then
            table.remove(_color, k)
            break
        end
    end
    --log.info("first _color=", _color)
    if _color and next(_color) then 
        --某花色第一、二轮出牌
        card = do_out_color_first(handcards, main_color, _color[1], outcard_history, _color)
        if card then 
            uu.debug_logic(33)
            return card
        else
            log.error("do_out_color_first error!")
        end
    else
        --是否有某种花色第3轮出牌
        local _color_ = uu.history_check_color_third_out(outcard_history_more, handcards)
        --log.info("third _color_=", _color_)
        if _color_ and next(_color_) then
            card = gg.get_more_color_min_card_by_colors(handcards, _color_)
            --log.info("card=",card)
            if card then
                uu.debug_logic(34)
                return card
            else
                card = uu.get_more_color_min_card(handcards)
                return card
            end
        else
            --是否某种花色第一、二轮出牌
            local _color_t = uu.history_check_color_first_out(outcard_history_more, handcards)
            --log.info("history_check_color_first_out _color_t=", _color_t)
            --策划说要去主牌
            for k, v in pairs(_color_t) do
                if v==main_color then
                    table.remove(_color_t, k)
                    break
                end
            end
            if _color_t then 
                --某花色第一、二轮出牌
                card = do_out_color_first(handcards, main_color, _color_t[1], outcard_history, _color_t)
                if card then 
                    uu.debug_logic(35)
                    return card
                else
                    log.error("do_out_color_first error!")
                end
            else
                --吊主逻辑
                card = do_diao_zhu(handcards, main_color, outcard_history, enemy_no_color_t)
                if card then 
                    uu.debug_logic(36)
                    return card
                else
                    local main_cards_count = gg.get_main_card_count(handcards, main_color)
                    if main_cards_count > 0 then
                        --出最小的主牌
                        uu.debug_logic(37)
                        card = uu.get_color_min_card(handcards, main_color)
                    else
                        uu.debug_logic(44)
                        card = uu.history_check_less_color_or_min_card(handcards, outcard_history)
                    end
                    if card then
                        return card
                    else
                        log.error("get_color_min_card && history_check_less_color_or_min_card error!")
                    end 
                end
            end
        end
    end
end

--============================= Api =============================--
function M.do_card(handcards, is_call_score_team, main_color, outcard_history, enemy_no_color_t, friend_no_color_t,
        current_round, is_first_out_last_round, last_round_outcard, outcard_history_more, m_seatid)
    --[[
    log.info("-------------------------------------------")
    log.info("handcards=", handcards)
    log.info("is_call_score_team=", is_call_score_team)
    log.info("main_color=", main_color)
    log.info("outcard_history=", outcard_history)
    log.info("enemy_no_color_t=", enemy_no_color_t)
    log.info("friend_no_color_t=", friend_no_color_t)
    log.info("current_round=", current_round)
    log.info("is_first_out_last_round=", is_first_out_last_round)
    log.info("last_round_outcard=", last_round_outcard)
    log.info("-------------------------------------------")
    --]]
    --local handcards = uu.clone_table(handcards_s)

    if __LOG_LEVEL___==1 then
        local tmp = {}
        for _, v in ipairs(handcards) do
            table.insert(tmp, string.format("%04X", v))
        end
        uu.debug_logic(tmp)
    end


    local flag, card
    --是否最后两张牌了
    flag, card = check_do_last_card(handcards, main_color, outcard_history, enemy_no_color_t, friend_no_color_t)
    if flag then
        if card then
            uu.debug_logic(38)
            return card
        else
            log.error("do_card check_do_last_card error!")
        end
    end

    --是否第一回合
    if not gg.check_is_round_1(current_round) then 
        --非第一回合检测上一回合是否第一个出
        if is_first_out_last_round then 
            --结合出牌历史：上一回合所出的牌是否不是该花色中最大的牌
            if not gg.check_last_rount_max_card(handcards, outcard_history, last_round_outcard) then
                --检测该花色牌是否只出了一回合
                if gg.check_card_color_out_1(last_round_outcard, outcard_history_more) then
                    --出该花色中等偏大的牌
                    local color = uu.calc_card_color(last_round_outcard)
                    card = uu.get_color_middle_card(handcards, color)
                    --if not card then
                        --card = do_out_color_first(handcards, main_color, color, outcard_history)
                    --end
                    if card then
                        uu.debug_logic(39)
                        return card
                    end
                end
            end
        end
    end

    --先执行非叫分队逻辑，若无法出牌则走叫分队出最大牌逻辑(策划的意思是这个逻辑是共用的只是名字有歧义)
    if not is_call_score_team then
        flag, card = do_card_not_call_score_team(handcards, main_color, outcard_history, enemy_no_color_t, m_seatid, outcard_history_more)
        if card then 
            uu.debug_logic(40)
            return card
        end
    else
        flag = true
    end
    
    --流程图里是非叫分队检测规则不通过后还要回到外层去执行叫分队出最大牌逻辑
    if flag==true then 
        card = do_card_call_score_team(handcards, main_color, outcard_history, enemy_no_color_t, m_seatid, outcard_history_more)
        if card then 
            uu.debug_logic(41)
            return card
        end
    end

    --log.info("enemy_no_color_t=", enemy_no_color_t)
    --log.info("friend_no_color_t=", friend_no_color_t)
    --流程图中所画的公共逻辑
    uu.debug_logic("do_common_logic")
    card = do_common_logic(handcards, main_color, outcard_history, enemy_no_color_t, friend_no_color_t, outcard_history_more)
    local round_color
    if card then
        round_color = uu.calc_card_color(card)
    end
    
    --最后的容错
    local the_flag, the_card = gg.check_error_card(handcards, card, round_color, 1)
    if the_flag==true then
        uu.debug_logic(42)
        card = the_card
    end

    uu.debug_logic(43)
    return card
end

return M